"""
fileserverwidget.views

"""

# This line just better work...
from jackson import debug

# There's debug stuff for the rest
debug.pre_import(__name__)

debug.importing(__name__, 'ChooseFileNameForm, UploadFileForm from fileserverwidget.models')
from fileserverwidget.models import ChooseFileNameForm, UploadFileForm

debug.importing(__name__, 'regisert_key, get_url from jackson.cdn.client.api')
from jackson.cdn.client_api import register_key, get_url

from jackson.utils import gen_hash

debug.importing(__name__, 'forms from django', 2)
from django import forms

debug.importing(__name__, 'settings from django.conf', 2)
from django.conf import settings

debug.importing(__name__, 'HttpResponseRedirect, HttpResponse, Http404 from django.http', 2)
from django.http import HttpResponseRedirect, HttpResponse, Http404, HttpResponseNotFound

debug.importing(__name__, 'reverse from django.core.urlresolvers', 2)
from django.core.urlresolvers import reverse

debug.importing(__name__, 'render_to_string from django.template.loader', 2)
from django.template.loader import render_to_string

debug.importing(__name__, 'atoi from string', 3)
from string import atoi

debug.importing(__name__, "choice from random", 3)
from random import choice

debug.importing(__name__, "hashlib", 3)
import hashlib

debug.importing(__name__, "magic", 2)
import magic

from jackson.cdn.net import download_content

debug.post_import(__name__)

# Debugging / Test
def index(request):
    context = [__name__, 'index()']
    debug.enter(context, None, 3)
    t = render_to_string('base.html',
            {'sidebar':'asdf','centered_title': choice(settings.DEFAULT_ERROR_MESSAGES)})
    debug.leave(context, None, 3)
    return HttpResponse(t)


def download(request):
    """
    Handles the download form.  Checks the request method and serves an empty form,
    otherwise it tries to redirect to the file.  If CDN doesn't know about the file, a 404 is returned.
    
    @todo: check (in addition to the request method) the required fields so  we can tell if 
            the response is actually a submitted form or not, to fix that stupid safari bug.
    
    """
    # let the debug framework know that this function has been called
    context = [__name__, 'download()']
    debug.enter(context, None, 3)
    # r will be our response. 
    r = None
    if request.method == 'POST':
        # @todo: implement this
        # rttopt layer /download forwards should download the file, then serve it
        
        #
        # - take filename from the form, after it's cleaned
        # - download the file and write to disk locally with cdn.net.download_content(url,local_filename)
        # - then redirect to hash(filename) so lighttpd can serve it
        #

        # if request.method is POST, the form has been submitted
        f = ChooseFileNameForm(request.POST)
        if f.is_valid():
            filename = f.cleaned_data['filename']
            # get the url (from the MD5 hash)
            url = get_url(gen_hash(filename))
            # @change: robert on march 14: check for DNE
            if url == "DNE":
                message = 'file \"' + filename + '\" not found'
                f = ChooseFileNameForm(request.POST)
                t = render_to_string('download.html', {'form': f, 'error_text': message})
                r = HttpResponse(t, status=404)
            else:                
                r = HttpResponseRedirect(url)
    else:
        f = ChooseFileNameForm()
        t = render_to_string('download.html', {'form':f})
        r = HttpResponse(t)
    debug.leave(context, None, 3)
    return r


def upload(request):
    """
    Handles the upload form.
    @todo: fix the safari bug where the form is processed as a GET sometimes
    @todo we can do this by checking (in the first branch) if one of the required fields is filled
    """
    context = [__name__, 'upload()']
    debug.enter(context, {"request":"suckers. i'm not printing all that"})
    # keep this useless line!
    debug.comment(context, 'post:' + str(request.POST), 3) # !!! @BUG!!! accessing POST fixed a problem involving reading POST data!
    debug.comment(context, 'meta:' + str(request.META), 3)
    debug.comment(context, 'raw post:' + str(request.raw_post_data), 3)
    r = None
    # check if 'title' is in the combined get/request REQUEST field
    debug.comment(context, "processing a " + request.method + "-type response ")
    debug.comment(context, "'title' in request.REQUEST? " + str('title' in request.POST))
    if request.method == 'POST' or 'title' in request.REQUEST:
        debug.comment(context, 'processing a POST-type HTTP object')
        try:
            debug.comment(context, 'about to load the form.', 3);
            form = UploadFileForm(request.POST, request.FILES)
            debug.comment(context, 'form loaded, is_bound:' + str(form.is_bound), 3)
            debug.comment(context, 'form.is_valid():' + str(form.is_valid()), 3)
            debug.comment(context, str(form.errors), 3)
            if form.is_bound and form.is_valid():
                debug.comment(context, 'setting the filename', 3)
                filename = request.POST['title'] # assuming this is of type <str>
                debug.comment(context, 'done setting filename. it is ' + filename, 2)
                # Compute hash of filename
                m = hashlib.md5()
                m.update(filename)
                file_key = m.hexdigest()
                # write to a file.
                f = request.FILES['fileobj']
                fq_filename = settings.LIGHTTPD_DOC_ROOT + str(file_key)
                debug.comment(context, "full path to file:" + fq_filename)
                dst = open(fq_filename,'w')
                for chunk in f.chunks(): # grab the first file they uploaded.
                    dst.write(chunk)
                dst.close()
                mimetype = magic.from_file(fq_filename, True)
                register_key(file_key,
                             'http://' + settings.MY_IP + ':' + str(settings.MY_PORT) + '/' + file_key,
                             new_filename=filename, new_mimetype=mimetype)
                message = "file \"" + filename + "\" successfully uploaded!"
                form = UploadFileForm()
                t = render_to_string('upload.html',{'form':form, 'error_text': message})
                r = HttpResponse(t)
            else:
                t = render_to_string('upload.html',{'form': form})
                r = HttpResponse(t)
        except Exception, e:
            debug.exception(context, str(e))
            t = render_to_string('upload.html', {'error_text': str(e), 'form': form})
            r = HttpResponse(t)
    else: # not POST
        debug.comment(context, "not POST", 3)
        f = UploadFileForm()
        debug.comment(context, "form has been built", 3)
        t = render_to_string('upload.html',{'form':f})
        debug.comment(context, "form has been rendered to a string, about to return", 3)
        r = HttpResponse(t)
    debug.leave(context, {'response':"html removed for brevity"})
    return r


def detect_max_redirects(request, k):
    context = [__name__, 'detect_max_redirects()']
    debug.enter(context, {'k' : k}, 3)
    debug.leave(context, None, 3)
    return HttpResponseRedirect(reverse('mysite.views.detect_max_redirects', args=(str(atoi(k)+1),)))
